#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Sockets Connection Manager Class
 *      Provides a thread-safe management class for multiple Socket connection
 * instances.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "stdafx.h"
#include "SocketsClient.h"
#include "SocketsConnection.h"
#include "SocketsConnectionCollection.h"

using namespace System;
using namespace Adaptive;
using namespace Adaptive::Foundation;

namespace Adaptive
{
	namespace Network
	{
		namespace Sockets
		{
			/// <summary>
			/// Provides a thread-safe management class for multiple Socket connection instances.
			/// </summary>
			public ref class SocketsConnectionManager : public AiObjectBase
			{
			public:
				/*------------------------------------------------------------------------
				 * Public Event Declarations
				 *----------------------------------------------------------------------*/
				#pragma region Public Event Declarations
				/// <summary>
				/// Occurs when a managed item receives data.
				/// </summary>
				event DataReceivedEventHandler^ DataReceived;
				/// <summary>
				/// Occurs when a managed item sends data.
				/// </summary>
				event DataSentEventHandler^ DataSent;
				/// <summary>
				/// Occurs when a managed item's connection is closed or disconnected.
				/// </summary>
				event ConnectionEventHandler^ ClientDisconnect;
				#pragma endregion

				/*------------------------------------------------------------------------
				 * Constructor / Dispose / Destructor Methods
				 *----------------------------------------------------------------------*/
				#pragma region Constructor / Dispose / Destructor Methods
				/// <summary>
				/// Initializes a new instance of the class
				/// </summary>
				/// <remarks>
				/// This is the default constructor.
				/// </remarks>
				SocketsConnectionManager();
				/// <summary>
				/// Class destructor.
				/// </summary>
				~SocketsConnectionManager();
				/// <summary>
				/// Class destructor.
				/// </summary>
				!SocketsConnectionManager();
				#pragma endregion

				/*------------------------------------------------------------------------
				 * Public Properties
				 *----------------------------------------------------------------------*/
				#pragma region Public Properties
				/// <summary>
				/// Gets the number of items being managed.
				/// </summary>
				/// <value>
				/// The number of connections currently being managed.
				/// </value>
				property int Count { int get(); }
				#pragma endregion

				/*------------------------------------------------------------------------
				 * Public Methods / Functions
				 *----------------------------------------------------------------------*/
				#pragma region Public Methods / Functions
				/// <summary>
				/// Adds a new <b>ISocketConnection</b> to be managed.
				/// </summary>
				/// <param name="newInstance">
				/// A new <see cref="ISocketConnection"/> instance to be added to the manager.
				/// </param>
				void Add(ISocketConnection^ newInstance);
				/// <summary>
				/// Adds the contents of the <b>ISocketConnection</b> array to be managed.
				/// </summary>
				/// <param name="newInstanceList">
				/// An array of <see cref="ISocketConnection"/> instances to be added to the manager.
				/// </param>
				void AddRange(array<ISocketConnection^>^ newInstanceList);
				/// <summary>
				/// Closes and destroys all connections currently being managed.
				/// </summary>
				/// <remarks>
				/// This method will block until all items are disposed of.
				/// </remarks>
				void CloseAll();
				/// <summary>
				/// Asynchronously closes and destroys all connections currently being managed.
				/// </summary>
				/// <remarks>
				/// This method will being the process of closing and disposing of all internal objects
				/// in an asynchronous fashion.  This method is non-blocking.
				/// </remarks>
				void AsyncCloseAll();
				#pragma endregion

			protected:
				/*------------------------------------------------------------------------
		         * Event Methods / Functions
				 *----------------------------------------------------------------------*/
				#pragma region Event Methods / Functions
				/// <summary>
				/// Raises the <see cref="DataReceived"/> event.
				/// </summary>
				/// <remarks>
				/// Unlike the standard model, this method requires the <see cref="ISocketConnection"/> instance
				/// to specified to any event subscribers.
				/// </remarks>
				/// <param name="client">
				/// A <see cref="ISocketConnection"/> instance that received new data.
				/// </param>
				/// <param name="e">
				/// A <see cref="DataReceivedEventArgs"/> event arguments instance containing the data.
				/// </param>
				virtual void OnDataReceived(ISocketConnection^ client, DataReceivedEventArgs^ e);
				/// <summary>
				/// Raises the <see cref="DataSent"/> event.
				/// </summary>
				/// <remarks>
				/// Unlike the standard model, this method requires the <see cref="ISocketConnection"/> instance
				/// to specified to any event subscribers.
				/// </remarks>
				/// <param name="client">
				/// A <see cref="ISocketConnection"/> instance that sent new data.
				/// </param>
				/// <param name="e">
				/// A <see cref="DataSentEventArgs"/> event arguments instance containing the data.
				/// </param>
				virtual void OnDataSent(ISocketConnection^ client, DataSentEventArgs^ e);
				/// <summary>
				/// Raises the <see cref="ClientDisconnect"/> event.
				/// </summary>
				/// <param name="e">
				/// A <see cref="ConnectionEventArgs"/> event arguments instance containing the reference to
				/// the <see cref="ISocketConnection"/> instance that lost the connection.
				/// </param>
				virtual void OnClientDisconnect(ConnectionEventArgs^ e);
				#pragma endregion

				/*------------------------------------------------------------------------
		         * Protected Methods / Functions
				 *----------------------------------------------------------------------*/
				#pragma region Protected Methods / Functions
				#pragma endregion
			
			private:
				/*------------------------------------------------------------------------
		         * Private Member Declarations
				 *----------------------------------------------------------------------*/
				#pragma region Private Member Declarations

				SocketsConnectionCollection^	_connections;

				#pragma endregion

				/*------------------------------------------------------------------------
		         * Private Methods / Functions
				 *----------------------------------------------------------------------*/
				#pragma region Private Methods / Functions

				void HandleDataReception(Object^ sender, DataReceivedEventArgs^ e);
				void HandleDataSend(Object^ sender, DataSentEventArgs^ e);
				void HandleDisconnect(Object^ sender, EventArgs^ e);
				#pragma endregion
			};
		}
	}
}
